package com.chixing.utils;

import com.chixing.entity.Users;
import com.chixing.entity.VO.LoginUser;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;

import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;


//封装 ， 解析 ，验证
public class JWTUtils {
    private static final String jwtToken = "MySuperSecretKeyForJwtToken1234567890";
    private static long expireTime = 1000 * 60 * 60 * 24;

    private static Key getSigningKey(){
        return Keys.hmacShaKeyFor(jwtToken.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 将用户的登录信息封装成token
     * @param user 用户信息
     * @return 封装成token
     */
    public static String createToken(Users user){
        HashMap<String, Object> claims = new HashMap<>();
        //将用户信息先封装到map里
        claims.put("userId",user.getUserId());
        claims.put("userName",user.getUserName());
        claims.put("userPhone",user.getPhone());
        claims.put("userEmail",user.getUserEmail());

        JwtBuilder jwtBuilder = Jwts.builder().signWith(getSigningKey(), SignatureAlgorithm.HS256)//签发算法，密钥为jwtToken
                .setClaims(claims)//body数据，要唯一，自行色湖之，payload部分数据
                .setIssuedAt(new Date())//设置签发时间：保证每次生成的token不同
                .setExpiration(new Date(System.currentTimeMillis() + expireTime));//设置token一天的有效时间
        String token = jwtBuilder.compact();
        return token;
    }

    /**
     * 解析token
     * @param token 用户的token
     * @return  返回用户的登录信息
     */
    public static LoginUser parseToken(String token){
        if (token!=null && !token.equals("")){
           try {
               Claims claims = Jwts.parserBuilder()
                       .setSigningKey(getSigningKey())//使用一致的key
                       .build()
                       .parseClaimsJws(token)
                       .getBody();
               if (claims != null){
//                   String userIdStr  = claims.get("userId", String.class);
//                   Integer userId = userIdStr != null ? Integer.valueOf(userIdStr ) : null;
                   Object userIdObj = claims.get("userId");
                   Integer userId = Integer.valueOf(userIdObj.toString());
                   String userName = claims.get("userName", String.class);
//                   Long userPhone = claims.get("userPhone", Long.class);
                   Object phoneObj = claims.get("userPhone");
                   Long userPhone = Long.valueOf(phoneObj.toString());
                   String userEmail = claims.get("userEmail", String.class);

                   LoginUser loginUser = new LoginUser(userId, userName, userPhone, userEmail);
                   System.out.println("获得到的用户登陆信息是 ：" +loginUser);
                   return loginUser;
               }else {
                   System.out.println("获得用户登录信息失败");
                   return null;
               }
           }catch (Exception e){
               e.printStackTrace();
               System.out.println("parseToken jwt token已经过期，需要重新登录");
               return null;
           }
        }else
            return null;
    }

    /**
     * 验证当前的token是否有效
     * @param token 用户的token信息
     * @return 有效：true ； 无效，过期：false
     */
    public static int checkToken(String token){
        System.out.println("获得到的token是："+ token);
        if (token != null && !token.equals("")){
            try {
                Jwts.parserBuilder().setSigningKey(getSigningKey())
                        .build()
                        .parseClaimsJws(token);
                return  ResultCode.VALID_TOKEN;
            }catch (ExpiredJwtException e){
                e.printStackTrace();
                System.out.println("checkToken jwt token已经过期，需要重新登录");
                return ResultCode.EXPIRE_TOKEN;
            }catch (SignatureException e){
                e.printStackTrace();
                System.out.println(" checkToken jwt无效的签名111,token无效");
                return ResultCode.ERROR_TOKEN;
            }catch (MalformedJwtException e){
                e.printStackTrace();
                System.out.println("checkToken jwt无效的签名222,token无效");
                return ResultCode.ERROR_TOKEN;
            }
        }else
            return ResultCode.ERROR_TOKEN;
    }


}
